package cn.us.eagle.generic.dao.hibernate;

import java.io.Serializable;
import java.util.List;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import cn.us.eagle.generic.dao.BaseDao;

/**
 * 继承式泛型DAO实现类（基于hibernate4）
 * 
 * @author ReasonZhong
 * 
 * @param <T>
 *            泛型类
 * @param <PK>
 *            泛型类主键
 */
public class BaseDaoImpl<T, PK extends Serializable> implements BaseDao<T, PK> {

	protected static final Logger LOGGER = LoggerFactory
			.getLogger(BaseDaoImpl.class);

	private final Class<T> entityClass;
	private final String HQL_LIST_ALL;
	private final String HQL_COUNT_ALL;

	public BaseDaoImpl(final Class<T> entityClass) {
		this.entityClass = entityClass;

		// TODO @Entity name not null
		HQL_LIST_ALL = "from " + this.entityClass.getSimpleName();
		HQL_COUNT_ALL = " select count(*) from "
				+ this.entityClass.getSimpleName();
	}

	@Autowired
	@Qualifier("sessionFactory")
	private SessionFactory sessionFactory;

	public Session getSession() {
		// 事务必须是开启的(Required)，否则获取不到
		return sessionFactory.getCurrentSession();
	}

	@SuppressWarnings("unchecked")
	@Override
	public PK save(T model) {
		return (PK) this.getSession().save(model);
	}

	@Override
	public void saveOrUpdate(T model) {
		this.getSession().saveOrUpdate(model);
	}

	@Override
	public void update(T model) {
		this.getSession().update(model);
	}

	@Override
	public void merge(T model) {
		this.getSession().merge(model);
	}

	@Override
	public void delete(PK id) {
		this.getSession().delete(this.get(id));
	}

	@Override
	public void deleteObject(T model) {
		this.getSession().delete(model);
	}

	@SuppressWarnings("unchecked")
	@Override
	public T get(PK id) {
		return (T) this.getSession().get(this.entityClass, id);
	}

	@Override
	public int countAll() {
		Query query = getSession().createQuery(HQL_COUNT_ALL);
		Long total = (Long) query.uniqueResult();
		return total.intValue();
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<T> listAll() {
		Query query = getSession().createQuery(HQL_LIST_ALL);
		return query.list();
	}

	@Override
	public boolean isExists(PK id) {
		return get(id) != null;
	}

	@Override
	public void flush() {
		this.getSession().flush();
	}

	@Override
	public void clear() {
		this.getSession().clear();
	}

}
